<?xml version="1.0" encoding="UTF-8"?>
<!--
    NOTE: This transformation sheet is incomplete, it does not cater for 
    *all* wsdls. Missing is how to transform wsdl WITHOUT schema.
    
    Therefore, still to be included:
    1.  transformation when no schema is available
        (see:http://www.ibm.com/developerworks/webservices/library/ws-xsltwsdl/ 
        "listing 1")
        
        In this case above, the parameters (and their types) are defined within 
        wsdl message tags:
        
        <wsdl:message name="inputmsg1">
            <wsdl:part name="inputmsg1-part" type="xsd:string"/>
        </wsdl:message>
        
        Solution:
        Operation defines <input> and <output> message. If a schema does not 
        exist in the document, then check for <wsdl:message> items that match 
        those held in the current operation tag. From there, invoke a template 
        to generate UI for the wsdl message part in the same way this is acheived 
        for xsd:element items.        
-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                    xmlns:s="http://www.w3.org/2001/XMLSchema"
                    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
    <xsl:output method="html" encoding="utf-8" indent="yes"/>
    <!-- Key Operations -->
    <xsl:key match="wsdl:portType/wsdl:operation" name="operations" use="@name" />
    <!-- Key Elements -->
    <xsl:key match="s:element" name="elements" use="@name" />
    <!-- Key ComplexTypes -->
    <xsl:key match="s:complexType" name="complexTypes" use="@name" />
    <!-- Key Sequences -->
    <xsl:key match="s:sequence" name="sequences" use="@name" />
    <!-- Key SimpleTypes -->
    <xsl:key match="s:simpleType" name="simpleTypes" use="@name" />

    <xsl:variable name="TM" select="document('file:///C:/Users/csbeks/Documents/Visual Studio 2008/Projects/Novice/Novice1/Knowledge Base/Task Model/TaskModel.xml')"/>

    <xsl:template match="wsdl:portType">
        <xsl:if test="wsdl:operation">
            <xsl:apply-templates select="wsdl:operation"/>
        </xsl:if>
    </xsl:template>
    <!-- 
        Select all 'portype/operation' elements; this allows us to establish all 
        the operations supported by a webservice 
    -->
    <xsl:template name="operations" match="wsdl:portType/wsdl:operation">
        <xsl:variable name="op.name" select="@name"/>
        <div class="operation" id="{$op.name}">
            <!--<xsl:if test="//s:complexType/s:sequence/s:element">-->
            <xsl:if test="$TM//*[@operation = $op.name]">
                <h4>
                    <xsl:value-of select="$TM//*[@operation = $op.name]/@name" />
                    <br />
                </h4>
                <xsl:for-each select="key('operations',$op.name)">
                    <xsl:choose>
                        <xsl:when test="$TM//*[@operation = $op.name]/@type = 'display'">
                            <xsl:variable name="concat.op.name" select="concat($op.name,'Response')"/>
                            <xsl:for-each select="key('elements',$concat.op.name)">
                                <xsl:for-each select="descendant::s:element">
                                    <xsl:variable name="cur.el.name" select="@name"/>
                                    <xsl:choose>
                                        <xsl:when test="substring-before(@type, ':') ='tns'">
                                            <xsl:variable name="el.name" select="substring-after(@type, ':')" />
                                            <!--Perform check here for simpleType -->
                                            <xsl:for-each select="key('simpleTypes',$el.name)">
                                                <xsl:if test="child::s:restriction">
                                                    <!--<xsl:value-of select="$TM//*[@operation = $op.name]/@name" /> -->
                                                    <xsl:if test="current()/s:restriction[count(*) = 2]">
                                                        <xsl:variable name="curname" select="current()/@name"/>
                                                        <xsl:for-each select="current()/s:restriction/s:enumeration">
                                                            <input type="radio" name="$curname" value="false" class="radio display">
                                                                <!-- <xsl:attribute name="checked">unchecked</xsl:attribute> -->
                                                                <xsl:value-of select="@value"/>
                                                            </input>
                                                        </xsl:for-each>
                                                    </xsl:if>
                                                    <xsl:if test="current()/s:restriction[count(*) > 2]">
                                                        <select id="{@name}" class="dropdownlist display">
                                                            <xsl:for-each select="current()/s:restriction/s:enumeration">
                                                                <option value="{@value}">
                                                                    <xsl:value-of select="@value"/>
                                                                </option>
                                                            </xsl:for-each>
                                                        </select>
                                                    </xsl:if>
                                                </xsl:if>
                                            </xsl:for-each>
                                            <!--Perform check here for ComplexType -->
                                            <xsl:for-each select="key('complexTypes',$el.name)">
                                                <xsl:if test="child::s:sequence">
                                                    <!-- <xsl:value-of select="$TM//*[@operation = $op.name]/@name" /> -->
                                                    <xsl:for-each select=" current()/s:sequence/s:element">
                                                        <xsl:variable name="seq.el.name" select="@name"/>
                                                        <xsl:choose>
                                                            <xsl:when test="@type = 's:string'">
                                                                <div class="input">
                                                                    <xsl:if test="@maxOccurs = 1">
                                                                        <div class="inputName">
                                                                            <xsl:value-of select="@name"/>:
                                                                        </div>
                                                                        <!--<div id="{@name}" class="display"></div>-->
                                                                        <input type="text" id="{@name}" class="text display"/>
                                                                    </xsl:if>
                                                                    <!-- 1.	Text area (when item only displays) -->
                                                                    <xsl:if test="@maxOccurs = 'unbounded'">                                                                        
                                                                        <select id="{$op.name}" size='7' class="listBox dropdownlist">                                                                            
                                                                        </select>
                                                                    </xsl:if>
                                                                </div>
                                                            </xsl:when>
                                                          <!-- Added for 'SearchResults' type-->
                                                            <xsl:when test="substring-before(@type, ':') ='tns'">
                                                              <div class="input">
                                                                <xsl:if test="@maxOccurs = 1">
                                                                  <div class="inputName">
                                                                    <xsl:value-of select="@name"/>:
                                                                  </div>
                                                                  <!--<div id="{@name}" class="display"></div>-->
                                                                  <input type="text" id="{@name}" class="text display"/>
                                                                </xsl:if>
                                                                <!-- 1.	Text area (when item only displays) -->
                                                                <xsl:if test="@maxOccurs = 'unbounded'">
                                                                  <select id="{$op.name}" size='7' class="listBox dropdownlist">
                                                                  </select>
                                                                </xsl:if>
                                                              </div>
                                                            </xsl:when>
                                                        </xsl:choose>
                                                    </xsl:for-each>
                                                </xsl:if>
                                            </xsl:for-each>
                                            <!-- 
											check if this element is of a simpleType e.g. s:int or s:string etc. 
											If yes, then display its control. Otherwise, recursively find its simple elements and create controls for those instead.
										-->
                                        </xsl:when>
                                        <xsl:otherwise>
                                            <xsl:if test="@type = 's:string'">
                                                <div class="input">
                                                    <div class="inputName">
                                                        <xsl:value-of select="$TM//*[@operation = $cur.el.name]/@name" /> :
                                                    </div>
                                                    <input type="text" id="{@name}" class="text display"/>
                                                    <br />
                                                </div>
                                            </xsl:if>
                                        </xsl:otherwise>
                                    </xsl:choose>
                                </xsl:for-each>
                            </xsl:for-each>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:for-each select="key('elements',$op.name)">
                                <xsl:for-each select="descendant::s:element">
                                    <xsl:variable name="cur.el.name" select="@name"/>
                                    <xsl:choose>
                                        <!-- Check if the current element is defined by complex type (tns = target namespace)-->
                                        <xsl:when test="substring-before(@type, ':') ='tns'">
                                            <xsl:variable name="el.name" select="substring-after(@type, ':')" />
                                            <!--Perform check here for simpleType -->
                                            <xsl:for-each select="key('simpleTypes',$el.name)">
                                                <div class="input">
                                                    <div class="inputName">
                                                        <xsl:value-of select="$TM//*[@operation = $el.name]/@name"/> :
                                                    </div>
                                                    <xsl:if test="child::s:restriction">
                                                        <!--
																	<xsl:choose>
																		-->
                                                        <!-- Use the operator name -->
                                                        <!--
																		<xsl:when test="$el.name = 'string'"> 
																			<div class="inputName">
																						<xsl:value-of select="$TM//*[@operation = $op.name]/@name" /> :
																			</div>																			
																		</xsl:when>
																		-->
                                                        <!-- Use the simpleType name -->
                                                        <!--
																		<xsl:otherwise>
																			<xsl:variable name="cur.name" select="@name"/>
																			<div class="inputName">
																				<xsl:value-of select="$TM//*[@operation = $cur.name]/@name"/> 
																			</div>
																		</xsl:otherwise>
																	</xsl:choose>-->
                                                        <xsl:if test="current()/s:restriction[count(*) = 2]">
                                                            <xsl:variable name="curname" select="current()/@name"/>
                                                            <xsl:for-each select="current()/s:restriction/s:enumeration">
                                                                <input type="radio" name="$curname" value="false" class="radio">
                                                                    <xsl:value-of select="@value"/>
                                                                </input>
                                                            </xsl:for-each>
                                                        </xsl:if>
                                                        <xsl:if test="current()/s:restriction[count(*) > 2]">
                                                            <select id="{@name}" class="dropdownlist">
                                                                <xsl:for-each select="current()/s:restriction/s:enumeration">
                                                                    <option value="{@value}">
                                                                        <xsl:value-of select="@value"/>
                                                                    </option>
                                                                </xsl:for-each>
                                                            </select>
                                                        </xsl:if>
                                                    </xsl:if>
                                                </div>
                                            </xsl:for-each>
                                            <xsl:for-each select="key('complexTypes',$el.name)">
                                                <xsl:if test="child::s:sequence">
                                                    <xsl:value-of select="$TM//*[@operation = $op.name]/@name" />
                                                    <xsl:for-each select=" current()/s:sequence/s:element">
                                                        <xsl:variable name="seq.el.name" select="@name"/>
                                                        <xsl:choose>
                                                            <xsl:when test="@type = 's:string'">
                                                                <div class="input">
                                                                    <div class="inputName">
                                                                        <xsl:value-of select="@name"/>:
                                                                    </div>
                                                                    <input type="text" id="{@name}" class="text"/>
                                                                    <br />
                                                                </div>
                                                            </xsl:when>
                                                        </xsl:choose>
                                                    </xsl:for-each>
                                                </xsl:if>
                                            </xsl:for-each>
                                            <!-- 
																check if this element is of a simpleType e.g. s:int or s:string etc. 
																If yes, then display its control. Otherwise, recursively find its simple elements and create controls for those instead.
															-->
                                        </xsl:when>
                                        <!-- If the current element is NOT defined by a complex type then display a input element for it -->
                                        <xsl:otherwise>
                                            <div class="input">
                                                <!--  
                                    This section allows us to have a label for the textarea etc. However, the way i've implemented this currently
                                    allows us to simply use the operations name as the label. this is because textareas are web services of their
                                    own (as we implemented them).
                              -->
                                                <xsl:if test="$TM//*[@operation = $cur.el.name]">
                                                    <div class="inputName">
                                                        <xsl:value-of select="$TM//*[@operation = $cur.el.name]/@name" /> :
                                                    </div>
                                                </xsl:if>
                                                <xsl:choose>
                                                    <!-- 1.	Text area (when item only displays) -->
                                                    <xsl:when test="$TM//*[@operation = $op.name]/@content = 'textarea'">
                                                        <textarea id="{@name}"></textarea>
                                                    </xsl:when>
                                                    <!-- 2.	Simple Input -->
                                                    <xsl:otherwise>
                                                        <xsl:if test="@type = 's:string'">
                                                                <input type="text" id="{@name}" class="text"/>
                                                                <br />
                                                        </xsl:if>
                                                        <!-- Here do check for other data items e.g. int, double etc -->
                                                    </xsl:otherwise>
                                                </xsl:choose>
                                            </div>
                                        </xsl:otherwise>
                                    </xsl:choose>
                                </xsl:for-each>
                            </xsl:for-each>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:for-each>
            </xsl:if>
            <!--  
                NOTE: change from XPath expression to something more robust i.e: lose the /s:sequence/s:...
                REASON: this approach is not guaranteed to work in all cases. 
                        In particular, this approach does not correctly handle 
                        multi-file WSDL documents or inconsistent use of 
                        namespace prefixes within the WSDL document
                        (http://www.ibm.com/developerworks/webservices/library/ws-xsltwsdl/)
            -->
        </div>
    </xsl:template>
</xsl:stylesheet>